package com.hjh.usb.accessory.communication

import com.elvishew.xlog.XLog
import kotlinx.coroutines.*
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import java.io.InputStream

class AOAReceiver(
    private val mutex: Mutex,
    private val inputStreamProvider: () -> InputStream?,
    private val scope: CoroutineScope,
) {
    companion object {
        private const val BUFFER_SIZE = 1024
    }

    private var receiveJob: Job? = null

    @OptIn(ExperimentalStdlibApi::class)
    fun start() {
        receiveJob = scope.launch {
            val buffer = ByteArray(BUFFER_SIZE)

            while (isActive) {
                try {
                    val bytesRead = mutex.withLock {
                        inputStreamProvider()?.read(buffer) ?: -1
                    }

                    if (bytesRead > 0) {
                        val data = buffer.copyOf(bytesRead)
                        XLog.tag("Accessory Receive").i(data.toHexString(HexFormat.UpperCase))
                        UsbFlow.updateData(data)
                    } else if (bytesRead == -1) {
                        throw Exception("输入流已结束")
                    }
                } catch (e: Exception) {
                    UsbFlow.updateConnectionState(
                        ConnectionState.Error("接收错误: ${e.message}")
                    )
                    break
                }
            }
        }
    }

    fun stop() {
        receiveJob?.cancel()
        receiveJob = null
    }
}
